package com.rajaev.dtu.tractor.app.scheduleTask;

import cn.hutool.core.util.ObjectUtil;
import com.rajaev.dtu.tractor.app.service.BatteryService;
import com.rajaev.dtu.tractor.app.service.FaultService;
import com.rajaev.dtu.tractor.domain.entity.BatteryInspectTaskDetail;
import com.rajaev.dtu.tractor.domain.repository.mysql.FaultLevelDao;
import com.rajaev.dtu.tractor.domain.repository.redis.DeviceMonitorRedisRepository;
import com.rajaev.dtu.tractor.domain.repository.redis.FaultCodeRedisRepository;
import com.rajaev.dtu.tractor.domain.vo.BatteryMonitorVo;
import com.rajaev.dtu.tractor.domain.vo.FaultDetailVo;
import com.rajaev.dtu.tractor.infrastructure.base.common.Constants;
import com.rajaev.dtu.tractor.infrastructure.helper.BeanUtils;
import com.rajaev.dtu.tractor.infrastructure.helper.MongoDbUtils;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;

import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;

/**
 * @Created with IDEA
 * @author: tianjie
 * @Date:2019/4/11
 * @Time:11:53
 */
@Slf4j
@Getter
public class BatterInspectCaller implements Callable<Boolean>, ApplicationContextAware {


    private Integer taskId;

    private String vin;


    private static BatteryService batteryService;

    private static FaultLevelDao faultLevelDao;

    private static MongoDbUtils mongoDbUtils;

    private static DeviceMonitorRedisRepository deviceMonitorRedisRepository;


    private static FaultCodeRedisRepository faultCodeRedisRepository;


    private static FaultService faultService;

    public BatterInspectCaller(Integer taskId, String vin) {
        this.taskId = taskId;
        this.vin = vin;
    }

    @Override
    public Boolean call() {
        log.info("start inspect battery vin:{} ", vin);
        BatteryMonitorVo batteryMonitorVo = batteryService.selectByVin(vin);
        //RedisLockRegistry redisLockRegistry = new RedisLockRegistry("1");

        //判断如果车辆10分钟内没有上报数据，则对该电池不执行巡检
        if (System.currentTimeMillis() - batteryMonitorVo.getTickTime() * 1000 >= 10 * 60 * 1000) {

            return false;
        }


        BatteryInspectTaskDetail batteryInspectTaskDetail = inspect(batteryMonitorVo);
        Map<String, Object> inspectionMap = BeanUtils.beanToMap(batteryInspectTaskDetail);
        inspectionMap.put("state", 1);
        inspectionMap.put("taskId", taskId);
        inspectionMap.put("vin", vin);
        mongoDbUtils.getDatabase().getCollection(Constants.batteryInspectTaskCollectionName)
                .updateOne(and(eq("taskId", taskId), eq("vin", vin)), new Document("$set", new Document(inspectionMap)));

        return true;
    }


    private BatteryInspectTaskDetail inspect(BatteryMonitorVo carMonitorData) {
        BatteryInspectTaskDetail batteryInspectTaskDetail = new BatteryInspectTaskDetail();
        batteryInspectTaskDetail.setInspectStartTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        batteryInspectTaskDetail.setBz(carMonitorData.getBz());
        batteryInspectTaskDetail.setPlateNo(carMonitorData.getPlateNo());
        batteryInspectTaskDetail.setMaxSingleV(carMonitorData.getMaxSingleV());

        //soc评分
        if (carMonitorData.getSoc() != null) {
            batteryInspectTaskDetail.setSoc(carMonitorData.getSoc());
        } else {
            batteryInspectTaskDetail.setSoc(carMonitorData.getSoc());
        }
        int faultLevel = deviceMonitorRedisRepository.getDeviceMonitor(carMonitorData.getVin()).getDcgzdj();
        batteryInspectTaskDetail.setSystemFaultLevel(ObjectUtil.isNotNull(faultLevel) ? Integer.parseInt(String.valueOf(faultLevel)) : null);
        ;

        //最高温度评分
        if (carMonitorData.getMaxTStr() != null) {
            batteryInspectTaskDetail.setMaxTStr(carMonitorData.getMaxTStr());
            batteryInspectTaskDetail.setMinTStr(carMonitorData.getMinTstr());
        }


        //压差评分,单位 毫伏
        BigDecimal vSub = new BigDecimal(carMonitorData.getMaxSingleV()).subtract(new BigDecimal(carMonitorData.getMinSingleV())).multiply(new BigDecimal(1000));
        batteryInspectTaskDetail.setSubV(vSub.intValue());


        //故障评分,当前无故障，f=1
        if (carMonitorData.getFault_num() == 0) {

            batteryInspectTaskDetail.setMaxFaultLevel(0);
        } else {
            List<FaultDetailVo> list = faultService.selectNotOveredFault(carMonitorData.getVin());
            if (list == null || list.size() == 0) {
                batteryInspectTaskDetail.setMaxFaultLevel(0);
            } else {
                FaultDetailVo faultDetailVo = list.stream().max(Comparator.comparing(FaultDetailVo::getFaultLevel)).get();
                batteryInspectTaskDetail.setFaultCode(String.valueOf(faultDetailVo.getFaultCode()));
                batteryInspectTaskDetail.setMaxFaultLevel(faultDetailVo.getFaultLevel());
                batteryInspectTaskDetail.setFaultDesc(faultDetailVo.getFaultDesc());
            }
        }


        batteryInspectTaskDetail.setInspectEndTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        return batteryInspectTaskDetail;
    }


    public static void main(String[] args) {
        String soc = "89.8";
        System.out.println(new BigDecimal(soc).setScale(1, RoundingMode.HALF_UP).floatValue());

    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        batteryService = applicationContext.getBean(BatteryService.class);
        faultLevelDao = applicationContext.getBean(FaultLevelDao.class);
        mongoDbUtils = applicationContext.getBean(MongoDbUtils.class);
        deviceMonitorRedisRepository = applicationContext.getBean(DeviceMonitorRedisRepository.class);
        faultCodeRedisRepository = applicationContext.getBean(FaultCodeRedisRepository.class);
        faultService = applicationContext.getBean(FaultService.class);
    }
}
